package com.hulk.boot.common.tool.jedis;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;

import com.google.common.base.Splitter;
import com.google.common.collect.Sets;

import lombok.Getter;
import lombok.Setter;
import redis.clients.jedis.JedisSentinelPool;

/**
 * @author cmt
 *
 */
public class JedisSentinelPoolFactoryBean  implements
		FactoryBean<JedisSentinelPool>, InitializingBean ,DisposableBean {

	

//	@Value(value = "${spring.redis.host}")
//	private String springRedisHost;
//
//	@Value(value = "${spring.redis.port}")
//	private String springRedisPort;

	

	@Setter
	@Getter
	private Integer database;
	@Setter
	@Getter
	private String sentinelMasterName;   //sentinel监听者名字
	@Setter
	@Getter
	private String sentinelNodes;  //地址结合 用逗号分割
	@Setter
	@Getter
	private Integer timeout;
	@Setter
	@Getter
	private String password ;
	@Setter
	@Getter
	private GenericObjectPoolConfig genericObjectPoolConfig;  //配置redis.clients.jedis.JedisPoolConfig
	
	@Setter
	@Getter
	private  JedisSentinelPool jedisSentinelPool;

	private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");

	@Override
	public void afterPropertiesSet() throws Exception {
		Set<String> haps = this.parseHostAndPort();
		
		jedisSentinelPool = new JedisSentinelPool(sentinelMasterName, haps, genericObjectPoolConfig, (int)timeout,(int)timeout,password,database,null);
	}

	@Override
	public JedisSentinelPool getObject() {
		return jedisSentinelPool;
	}

	@Override
	public Class<? extends JedisSentinelPool> getObjectType() {
		return (this.jedisSentinelPool != null ? this.jedisSentinelPool.getClass()
				: JedisSentinelPool.class);
	}

	@Override
	public boolean isSingleton() {
		return true;
	}
	
	private Set<String> parseHostAndPort()  {
		try {
			Iterable<String> parts = Splitter.on(',').trimResults()
					.omitEmptyStrings().split(sentinelNodes);
			final Set<String> clusterHosts = Sets.newHashSet(parts);
			//Set<HostAndPort> haps = new HashSet<HostAndPort>();
			Set<String> haps = new HashSet<String>();
			for (String host : clusterHosts) {
				String val = host;
				boolean isIpPort = p.matcher(val).matches();
				if (!isIpPort) {
					throw new IllegalArgumentException("Illegal IP or port");
				}
				haps.add(val.trim());
//				String[] ipAndPort = val.split(":");
//				HostAndPort hap = new HostAndPort(ipAndPort[0],Integer.parseInt(ipAndPort[1]));
//				haps.add(hap);
			}
			return haps;
		} catch (IllegalArgumentException ex) {
			throw  ex;
		} catch (Exception ex) {
			throw new RuntimeException("Failed to parse jedis configuration file", ex);
		}
	}


	
	
	@Override
	public void destroy() throws Exception {
		if (jedisSentinelPool != null) {
			jedisSentinelPool.destroy();
			jedisSentinelPool.close();
		}

	}
	
	
	
	/*public JedisSentinelPoolFactory(String masterName, Set<String> sentinels,
		GenericObjectPoolConfig poolConfig, Integer timeout) {
		super(masterName, sentinels, poolConfig, timeout);
	}*/
	
	/*
	 * <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
	 * 
	 * <property name="maxTotal" value="300"/> <property name="maxIdle"
	 * value="15"/> <property name="minIdle" value="3"/> <property
	 * name="testOnBorrow" value="true"/> </bean>
	 * 
	 * <bean id="jedisPool"
	 * class="cn.com.huateng.web.util.JedisSentinelPoolFactory">
	 * <constructor-arg index="0" value="${redis.clusterName}" />
	 * <constructor-arg index="1"> <set>
	 * <value>${redis.host42}:${redis.port}</value>
	 * <value>${redis.host43}:${redis.port}</value>
	 * <value>${redis.host44}:${redis.port}</value> </set> </constructor-arg>
	 * <constructor-arg index="2" ref="jedisPoolConfig"/> <constructor-arg
	 * index="3" value="30000" type="int"/> </bean>
	 * 
	 * <bean id="jedisTemplate" class="com.aixforce.redis.utils.JedisTemplate">
	 * <constructor-arg index="0" ref="jedisPool"/> </bean>
	 */
}